/*
 * Copyright (c) 2012, Kevin Doyle kfrdoyle@gmail.com . All rights reserved.
 * Kevin Doyle kfrdoyle@gmail.com. Use is subject to license terms.
 */
package gpsdata;

/**
 * GPSPoint is used by the Exocet versus Goalkeeper Simulation System 
 * to define GPS data types used for data storage.
 *
 * @author Kevin Doyle kfrdoyle[AT]gmail[DOT]com
 */
public class GPSPoint implements SystemConstants,PhysicsConstraints {

    /**
     * The Latitude coordinate of this
     * <code>GPSPoint</code>.
     *
     * @since 1
     */
    private double latitude;
    /**
     * The Longitude coordinate of this
     * <code>GPSPoint</code>.
     *
     * @since 1
     */
    private double longitude;
    
    /**
     * The gpsResolution of this
     * <code>GPSPoint</code>.
     *
     * @since 1
     */
    private double gpsResolution;
    
    /**
     * The timeStamp of this
     * <code>GPSPoint</code>. with time in UTC milliseconds from
     * the Java epoch of January 1, 1970 00:00:00.000 GMT (Gregorian).
     *
     * @since 1
     */
     private double timeStamp;

    /**
     * Constructs and initializes a
     * <code>GPSPoint</code> with coordinates (0,0,0).
     *
     * @since 1
     */
    public GPSPoint() {
        this.latitude = 0;
        this.longitude = 0;
        this.gpsResolution = 0;
        this.timeStamp = 0;
    }

    public GPSPoint(double latitude, double longitude, double gpsResolution, double timeStamp) {
        this.latitude = latitude;
        this.longitude = longitude;
        this.gpsResolution = gpsResolution;
        this.timeStamp = timeStamp;
    }

    /**
     * Returns the Latitude of this
     * <code>GPSPoint</code> in
     * <code>double</code> precision.
     *
     * @return the Latitude coordinate of this
     * <code>GPSPoint</code>.
     * @since 1
     */
    public double getLatitude() {
        return latitude;
    }

    /**
     * Returns the Longitude of this
     * <code>GPSPoint</code> in
     * <code>double</code> precision.
     *
     * @return the Longitude coordinate of this
     * <code>GPSPoint</code>.
     * @since 1
     */
    public double getLongitude() {
        return longitude;
    }

    /**
     * Returns the GPS Resolution of this
     * <code>GPSPoint</code> in
     * <code>double</code> precision.
     *
     * @return the GPS Resolution of this
     * <code>GPSPoint</code>.
     * @since 1
     */
    public double getGPSResolution() {
        return gpsResolution;
    }
    
        /**
     * Returns the Time Stamp of this
     * <code>GPSPoint</code> in
     * <code>double</code> precision.
     *
     * @return the Time Stamp of this
     * <code>GPSPoint</code>.
     * @since 1
     */
    public double getTimeStamp() {
        return timeStamp;
    }

    /**
     * Returns the GPS Location of this
     * <code>GPSPoint</code> in
     * <code>double</code> precision.
     *
     * @return the GPS Location of this
     * <code>GPSPoint</code>.
     * @since 1
     */
    public GPSPoint getLocation() {
        GPSPoint gpsp = new GPSPoint(0, 0, 0,0);
        gpsp.getLatitude();
        gpsp.getLongitude();
        gpsp.getGPSResolution();
        gpsp.getTimeStamp();
        return gpsp;
    }

    /**
     * Sets the location of this
     * <code>GPSPoint</code> to the specified
     * <code>double</code> coordinates.
     *
     * @param latitude the new Latitude coordinate of this {@code GPSPoint}
     * @param longitude the new Longitude coordinate of this {@code GPSPoint}
     * @param gpsResolution the new GPS Resolution of this {@code GPSPoint}
     * @param timeStamp the time in UTC this point was generated of this {@code GPSPoint}
     * @exception IllegalArgumentException if lat/long/res are not in range
     * @since 1
     */
    public void setLocation(double latitude, double longitude, double gpsResolution, double timeStamp) {
        if (!(latitude <= NORTH_POLE && latitude >= SOUTH_POLE)) {//-90° to +90° North to South
            throw new IllegalArgumentException("Latitude value '" + latitude + "' is not in range [-90°..+90°].");
        } else {
            this.latitude = latitude;
        }

        if (!(longitude >= MAX_WEST && longitude <= MAX_EAST)) {//-180° to +180° West to East
            throw new IllegalArgumentException("Longitude value '" + longitude + "' is not in range [-180°..+180°].");
        } else {
            this.longitude = longitude;
        }

        if (!(gpsResolution <= MAX_GPS_RESOLUTION && gpsResolution >= MIN_GPS_RESOLUTION)) {
            throw new IllegalArgumentException("GPS Resolution value '" + gpsResolution + "' is not in range.");
        } else {
            this.gpsResolution = gpsResolution;
        }
        
        if ((timeStamp <= 0)) {
            throw new IllegalArgumentException("Time Stamp value '" + timeStamp + "' is not valid.");
        } else {
            this.timeStamp = timeStamp;
        }


    }

    /**
     * Sets the location of this
     * <code>GPSPoint</code> to the same coordinates as the specified
     * <code>GPSPoint</code> object.
     *
     * @param gpsp the specified
     * <code>GPSPoint</code> to which to set this
     * <code>GPSPoint</code>
     * @since 1
     */
    public void setLocation(GPSPoint gpsp) {
        setLocation(gpsp.getLatitude(), gpsp.getLongitude(), gpsp.getGPSResolution(), gpsp.getTimeStamp());
    }

    /**
     * Returns a string representation of this point and its location in the {@code (x,y)}
     * coordinate space. This method is intended to be used only for debugging
     * purposes, and the content and format of the returned string may vary
     * between implementations. The returned string may be empty but may not be
     * <code>null</code>.
     *
     * @return a string representation of this point
     */
    @Override
    public String toString() {
        return getClass().getName() + "[latitude = " + latitude + 
                "\tlongitude = " + longitude + 
                "\tGPS resolution = " + gpsResolution + 
                "\tTime Stamp = "+timeStamp+"]";
    }
}